﻿//#define LOGGING

using System;
using System.Diagnostics;
using System.IO;
using System.Xaml;
using System.Xaml.Schema;

using alib;
using alib.Debugging;

namespace agree
{
	public sealed class xaml_xml_reader : XamlXmlReader
#if LOGGING
		, IDisposable
#endif
	{
		public xaml_xml_reader(Stream input_stream, XamlLoadInstance xli)
			: base(input_stream, xli.Schema.xsch)
		{
#if LOGGING
			if (log == null)
			{
				var fn = System.IO.Path.Combine(Environment.CurrentDirectory, String.Format("{0:yyyyMMdd\\-hhmmss}-{1}-{2}.txt", DateTime.Now, SysObj.Instance.BuildType, Path.GetFileNameWithoutExtension(xli.Filename)));
				log = new System.IO.StreamWriter(fn, false, System.Text.Encoding.UTF8);
				log.AutoFlush = true;
			}
#endif
		}
#if LOGGING
		System.IO.StreamWriter log;
		public void Dispose()
		{
			log.Close();
		}
#endif

		///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// 
		///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		[DebuggerStepThrough]
		public override bool Read()
		{
			var ret = base.Read();
			if (base.NodeType == XamlNodeType.StartObject && base.Type.UnderlyingType == typeof(Comment))
			{
				base.Skip();
				ret = base.IsEof;
			}
			return ret;
		}

		///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// 
		///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		public void transform(xaml_obj_writer xow)
		{
			while (Read())
			{
				if (xow.ShouldProvideLineInfo)
					xow.SetLineInfo(LineNumber, LinePosition);
#if LOGGING
				String log_txt = null;
#endif
				switch (NodeType)
				{
					case XamlNodeType.NamespaceDeclaration:
						xow.WriteNamespace(Namespace);
						break;

					case XamlNodeType.StartObject:
						xow.WriteStartObject(Type);
#if LOGGING
						log_txt = Type.Name;
#endif
						break;

					case XamlNodeType.EndObject:
						xow.inject_ctor_arg();
						xow.WriteEndObject();
						break;

					case XamlNodeType.StartMember:
						xow.inject_ctor_arg();
						xow.WriteStartMember(Member);
#if LOGGING
						log_txt = Member.Name;
#endif
						break;

					case XamlNodeType.EndMember:
						xow.WriteEndMember();
						break;

					case XamlNodeType.GetObject:
						xow.WriteGetObject();
						break;

					case XamlNodeType.Value:
						xow.WriteValue(Value);
#if LOGGING
						log_txt = Value.ToString();
#endif
						break;

					case XamlNodeType.None:
						break;
				}
#if LOGGING
				log.WriteLine("{0}:{1} {2} {3}", LineNumber, LinePosition, NodeType, log_txt ?? "");
#endif

			}
		}

		///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// 
		///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		public sealed class _settings : XamlXmlReaderSettings
		{
			public _settings(XamlLoadInstance xli)
			{
				//this.AllowProtectedMembersOnRoot = false;
				this.CloseInput = true;
			}
		};
	};
}
